package morenoapp.components.common;

import com.jgoodies.binding.adapter.TextComponentConnector;
import com.jgoodies.binding.beans.Model;
import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.beans.PropertyConnector;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import morenoapp.MorenoApp;
import morenoapp.action.MorenoActionsFacade;
import morenoapp.action.resources.ActionsResourcesHolder;
import morenoapp.util.I18N;
import morenoapp.util.MorenoUtil;

/**
 *
 * @author root
 */
public class ExceptionDialog extends JDialog {
    private static ExceptionDialog instance = null;
    ExceptionDialogModel model = new ExceptionDialogModel();
    JLabel labelMessage;
    JTextArea textStackTrace;
    JScrollPane scrollStackTrace;
    LinkLabel linkDescribe;
    JTextArea textDescription;
    JScrollPane scrollDescription;
    JButton buttonHide;
    JButton buttonSumbit;
    ExceptionDialog() {
        super();
        initComponents();
        initLayout();
    }

    private void initComponents() {
        { //this
            setIconImage(ActionsResourcesHolder.ICON_ACTION_ABOUT_SMALL.getImage());
            setTitle(I18N.get("exception_dialog.title"));
        }

        { //labelMessage
            JLabel label = new JLabel();
            PropertyConnector.connect(model, "message", label, "text");
            label.setName("labelMessage");
            labelMessage = label;
        }
        { //textStackTrace
            JTextArea text = new JTextArea();
            text.setName("textStackTrace");
            text.setTabSize(1);
            text.setEditable(false);
            PropertyConnector.connect(model, "stackTrace", text, "text");
            textStackTrace = text;
        }
        { //scrollStackTrace
            scrollStackTrace = new JScrollPane(textStackTrace);
            scrollStackTrace.setName("scrollStackTrace");
        }
        { //textDescription
            JTextArea text = new JTextArea();
            text.setName("textDescription");
            { //binding
                ValueModel valueModel = new PropertyAdapter(model, "description");
                TextComponentConnector connector = new TextComponentConnector(valueModel, text);
                connector.updateTextComponent();
            }
            textDescription = text;
        }
        {
            scrollDescription = new JScrollPane(textDescription);
            scrollDescription.setName("scrollDescription");
        }
        { //linkDescribe
            LinkLabel link = new LinkLabel();
            link.setName("linkDescribe");
            link.setText(I18N.get("exception_dialog.show_details"));
            link.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    applyLongView();
                }
            });
            linkDescribe = link;
        }

        { //buttonSumbit
            JButton button = new JButton();
            button.setName("buttonSumbit");
            button.setAction(MorenoActionsFacade.getActionExceptionDialogSubmit());
            buttonSumbit = button;
        }
        { //buttonHide
            JButton button = new JButton();
            button.setName("buttonHide");
            button.setAction(MorenoActionsFacade.getActionExceptionDialogHide());
            buttonHide = button;
        }
    }

    private void initLayout() {
        //setup dialog contents
        FormLayout layout = new FormLayout(
                //icon,,content
                "p, 3dlu, 400px:grow",
                "3dlu," + //space
                "50px, 3dlu, " + //message
                "p:grow, 3dlu, " + //exception if needed
                "p, 3dlu, " + //desctiption
                "p, " + //buttons
                ""); // rows

        //PanelBuilder builder = new PanelBuilder(layout, new FormDebugPanel()); //debug
        PanelBuilder builder = new PanelBuilder(layout);
        //builder.setDefaultDialogBorder();
        builder.setBorder(new javax.swing.border.EmptyBorder(5, 5, 5, 5));

        // Obtain a reusable constraints object to place components in the grid.
        CellConstraints cc = new CellConstraints();
        {
            { //warning-icon
                builder.add(new JLabel(ActionsResourcesHolder.ICON_MESSAGE_WARNING_60),
                        cc.rchw(2, 1,
                        layout.getRowCount() - 1, 1,
                        "top, default"));

            }

            int row = 1;
            { //error message
                row++;
                builder.add(labelMessage, cc.rcw(row, 3, layout.getColumnCount() - 2));
            }

            { //stack-trace
                row += 2;
                scrollStackTrace.setPreferredSize(new Dimension(200, 100));
                builder.add(scrollStackTrace, cc.rcw(row, 3, layout.getColumnCount() - 2, "fill, fill"));
            }
            { //description
                row += 2;
                scrollDescription.setPreferredSize(new Dimension(200, 100));
                builder.add(scrollDescription, cc.rcw(row, 3, layout.getColumnCount() - 2, "fill, fill"));
            }
            { //buttons at bototm
                row += 2;
                JPanel panelBox = MorenoUtil.createBoxLayoutPanel(BoxLayout.LINE_AXIS);
                panelBox.add(linkDescribe);
                panelBox.add(buttonSumbit);
                panelBox.add(Box.createHorizontalStrut(5));
                panelBox.add(buttonHide);
                //buttonSumbit.setVisible(false);

                builder.add(panelBox, cc.rc(layout.getRowCount(), layout.getColumnCount(), "default, right"));
            }

        }
        setContentPane(builder.getPanel());
        pack();
    }

    protected void applyShortView(boolean expandabe) {
        scrollStackTrace.setVisible(false);
        scrollDescription.setVisible(false);
        buttonSumbit.setVisible(false);
        linkDescribe.setVisible(expandabe);
        pack();
    }

    protected void applyLongView() {
        scrollStackTrace.setVisible(true);
        scrollDescription.setVisible(true);
        buttonSumbit.setVisible(true);
        linkDescribe.setVisible(false);
        pack();

    }

    public void submit() {
    }

    public static ExceptionDialog getInstance() {
        if (instance == null) {
            instance = new ExceptionDialog();
        }
        return instance;
    }

    public static void showDialog(String message, Throwable th) {
        ExceptionDialog dialog = getInstance();
        dialog.model.setMessage(message);
        dialog.model.setThrown(th);
        dialog.model.setDescription("");
        dialog.applyShortView(false);
        dialog.setLocationRelativeTo(MorenoApp.getApplication().getMainFrame());
        dialog.setModal(true);
        dialog.setVisible(true);
    }

    public static void showDialog(Throwable th) {
        ExceptionDialog dialog = getInstance();
        dialog.model.setMessage(String.valueOf(th.getMessage()));
        dialog.model.setThrown(th);
        dialog.model.setDescription("");
        dialog.applyShortView(true);
        dialog.setLocationRelativeTo(MorenoApp.getApplication().getMainFrame());
        dialog.setModal(true);
        dialog.setVisible(true);
        
    }


    public static void main(String[] args) {
        //MorenoLog.configureLogging();

        ExceptionDialog d = getInstance();
        d.addWindowListener(new WindowAdapter() {
            @Override
            public void windowDeactivated(WindowEvent e) {
                System.exit(0);
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }

        });
        d.setVisible(true);
        d.applyShortView(true);

        d.model.setMessage("Hello, somce problems occured...");
        d.model.setThrown(new Exception("Right here"));
        System.out.println("model changed successfully");
    }

    @Deprecated
    private enum ViewState {
        SHORT_VIEW,
        SHORT_VIEW_EXPANDABLE,
        LONG_VIEW;

        boolean expandedView;
        boolean expandButton;
        boolean ok;
    }


    public class ExceptionDialogModel extends Model {
        String message = "";
        Throwable thrown = null;
        String description = "";
        private ExceptionDialogModel() {
            super();
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String _description) {
            String oldValue = description;
            this.description = _description;
            this.firePropertyChange("description", oldValue, description);
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String _message) {
            String oldValue = message;
            this.message = _message;
            this.firePropertyChange("message", oldValue, message);
        }

        public String getStackTrace() {
            return MorenoUtil.toStirng(getThrown());
        }

        public Throwable getThrown() {
            return thrown;
        }

        public void setThrown(Throwable _thrown) {
            Throwable oldValue = this.thrown;
            this.thrown = _thrown;
            this.firePropertyChange("thrown", oldValue, thrown);
            this.firePropertyChange("stackTrace", "", getStackTrace());
        }

    }
}

